package com.demo.common.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import com.jfinal.plugin.activerecord.generator.TableMeta;

public class FKEngine {

	public static int _1_N = 0;
	public static int _1_1 = 1;

	/**
	 * Map<表,Map<字段,FK>,外键的来源只能是一个
	 * 主表的链接，key是从表
	 */
	protected HashMap<String, Map<String, FK>> masterLinks = new HashMap();
	/**
	 * Map<表,Map<字段,Map<从表.从表字段,FK>>,主表的主键可以作为多个从表的外键
	 * 从表的链接,key是主表
	 */
	protected HashMap<String, Map<String, Map<String, FK>>> slaveLinks = new HashMap();

	private FKEngine() {

	}
	
	public static FKEngine engine ;
	
	static {
		synchronized(FKEngine.class){
			engine = new FKEngine();
		} 
	}
	

	public void addFK(String expr) {
		// "material.parts -1:N- materialpart.parentmarterial"
		String masterTableName = null;
		String masterField = null;
		String masterAlias = null;
		int fktype = -1;
		String slaveTableName = null;
		String slaveField = null;
		String slaveAlias = null;
		if (expr == null)
			return;
		
		if(expr.indexOf("-1:N-") < 0 &&  expr.indexOf("-1:1-") < 0)
			return;
		
		String[] vars = expr.split("-1:N-"); 
		if (vars.length == 2) {
			// 1对多
			fktype = _1_N; 
		} else {
			vars = expr.split("-1:1-");
			fktype = _1_1; 
		}
		
		String[] tmp = vars[0].trim().split(" ");
		if (tmp.length > 1) {
			// 有别名
			String[] pf = tmp[0].trim().split("[.]");
			masterTableName = pf[0].trim();
			masterField = pf[1].trim();
			masterAlias = tmp[tmp.length-1];
		}else{
			String[] pf = vars[0].trim().split("[.]");
			masterTableName = pf[0].trim();
			masterField = pf[1].trim();
			masterAlias = masterTableName;
		}
		tmp = vars[1].trim().split(" ");
		if (tmp.length > 1) {
			// 有别名
			String[] ff = tmp[0].trim().split("[.]");
			slaveTableName = ff[0].trim();
			slaveField = ff[1].trim();
			slaveAlias = tmp[tmp.length-1];
		} else { 
			String[] ff = vars[1].trim().split("[.]");
			slaveTableName = ff[0].trim();
			slaveField = ff[1].trim();
			slaveAlias = slaveTableName;
		}

		addFK(masterTableName, masterField, masterAlias,  fktype, slaveTableName, slaveField, slaveAlias);
	}

	public void addFK(String masterTableName, String masterField, String masterAlias, int fktype, String slaveTableName,
			String slaveField, String slaveAlias) {
		FK fk = new FK();
		fk.masterTableName = masterTableName;
		fk.masterField = masterField;
		fk.masterAlias = masterAlias;
		fk.fktype = fktype;
		fk.slaveTableName = slaveTableName;
		fk.slaveField = slaveField;
		fk.slaveAlias = slaveAlias;

		Map<String, Map<String, FK>> slks = slaveLinks.get(fk.masterTableName);
		if (slks == null) {
			slks = new LinkedHashMap<String, Map<String, FK>>();
			slks.put(fk.masterField, new HashMap<String, FK>());
			slaveLinks.put(fk.masterTableName, slks);
		}
		slks.get(fk.masterField).put(fk.slaveTableName + "." + fk.slaveField, fk);

		Map<String, FK> mlks = masterLinks.get(fk.slaveTableName);
		if (mlks == null) {
			mlks = new LinkedHashMap<String, FK>();
			masterLinks.put(fk.slaveTableName, mlks);
		}
		mlks.put(fk.slaveField, fk);
	}

	/**
	 * 获取指定从表对应的主表关联关系s
	 * 
	 * @param slaveTableName
	 * @return
	 */
	public Map<String, FK> getMasterLinks(String slaveTableName) {
		return masterLinks.get(slaveTableName);
	}

	/**
	 * 获取指定从表，字段对应的主表关联关系
	 * 
	 * @param slaveTableName
	 * @return
	 */
	public FK getMasterLink(String slaveTableName, String slaveField) {
		Map<String, FK> ls = masterLinks.get(slaveTableName);
		return ls == null ? null : ls.get(slaveField);
	}

	/**
	 * 获取指定主表的从表关联关系s
	 * 
	 * @param masterTableName
	 * @return
	 */
	public Map<String, Map<String, FK>> getSlaveLinks(String masterTableName) {
		return slaveLinks.get(masterTableName);
	}

	/**
	 * 获取指定主表，字段对应的从表关联关系
	 * 
	 * @param masterTableName
	 * @param masterField
	 * @return
	 */
	public Map<String, FK> getSlaveLink(String masterTableName, String masterField) {
		Map<String, Map<String, FK>> ls = slaveLinks.get(masterTableName);
		return ls == null ? null : ls.get(masterField);
	}

	/**
	 * 获取指定主表，字段对应的从表关联关系
	 * 
	 * @param masterTableName
	 * @param masterField
	 * @param slaveTableAndField
	 *            从表表名.字段名
	 * @return
	 */
	public FK getSlaveLink(String masterTableName, String masterField, String slaveTableAndField) {
		Map<String, Map<String, FK>> ls = slaveLinks.get(masterTableName);
		if (ls == null)
			return null;
		Map<String, FK> fs = ls.get(masterField);
		return fs == null ? null : fs.get(slaveTableAndField);
	}

	public boolean isMasterFK(String masterTableName, String masterField) {
		Map<String, Map<String, FK>> ls = slaveLinks.get(masterTableName);
		return ls == null ? false : ls.get(masterField) != null;
	}

	public boolean isSlaveFK(String slaveTableName, String slaveField) {
		Map<String, FK> ls = masterLinks.get(slaveTableName);
		return ls == null ? false : ls.get(slaveField) != null;
	}
  

	public void initFKs() {
		//格式 主表.字段 [别名] -链接关系- 从表.字段 [别名] 
		//而 别名生成的字段是虚的属性
		addFK("material.id  material  -1:N- materialpart.parentid  parts");
		addFK("material.id   -1:1- materialinfo.materialid ");
	}

}
